package com.yricky.tsp;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;

import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.LinearLayout;
import android.widget.TextView;


import TSP.Entity;
import TSP.SolveSession;

public class PaintLayout extends LinearLayout
{
    public static final double PI=3.1415926;

    private SolveSession solveSession;
    // 画笔，定义绘制属性
    private Paint cityPaint;
    private Paint wayPaint;
    private Paint mBitmapPaint;

    // 绘制路径
    private Path cityPath;
    private Path wayPath;

    // 画布及其底层位图
    private Bitmap myBitmap;
    private Canvas mCanvas;

    boolean isRunning = false;
    private Handler handler;

    private OnCityAddListener onCityAddListener;
    private TextView textViewTurn;
    private TextView textViewDistance;
    private TextView textViewCP;
    private TextView textViewMR;
    /**
     * 初始化工作
     */
    private void initialize()
    {
        // Get a reference to our resource table.

        // 绘制自由曲线用的画笔
        cityPaint = new Paint();
        cityPaint.setAntiAlias(true);
        cityPaint.setDither(true);
        cityPaint.setColor(Color.argb(255,128,128,128));
        cityPaint.setStyle(Paint.Style.STROKE);
        cityPaint.setStrokeJoin(Paint.Join.ROUND);
        cityPaint.setStrokeCap(Paint.Cap.ROUND);
        cityPaint.setStrokeWidth(4);


        wayPaint = new Paint();
        wayPaint.setAntiAlias(true);
        wayPaint.setDither(true);
        wayPaint.setColor(Color.argb(255,192,64,64));
        wayPaint.setStyle(Paint.Style.STROKE);
        wayPaint.setStrokeJoin(Paint.Join.ROUND);
        wayPaint.setStrokeCap(Paint.Cap.ROUND);
        wayPaint.setStrokeWidth(3);
        cityPath = new Path();
        wayPath = new Path();
        mBitmapPaint = new Paint(Paint.DITHER_FLAG);

        handler=new Handler();
        solveSession=new SolveSession();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh)
    {
        super.onSizeChanged(w, h, oldw, oldh);
        myBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        float x = event.getX();
        float y = event.getY();
        if (event.getAction() == MotionEvent.ACTION_DOWN && !solveSession.isInitialized()) {
                addCity(x, y);
                invalidate();
        }
        return true;
    }

    @Override
    protected void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);
        mCanvas=canvas;
        // 如果不调用这个方法，绘制结束后画布将清空
        canvas.drawBitmap(myBitmap, 0, 0, mBitmapPaint);

        // 绘制路径
        canvas.drawPath(cityPath, cityPaint);
        canvas.drawPath(wayPath,wayPaint);
        //cityPaint.setTextSize(100);

        if(isRunning){
            textViewDistance.setText("D:"+solveSession.getCurrentKing().getDistance());
            textViewTurn.setText("T:"+solveSession.getTurnNum());
            textViewCP.setText("CP:"+solveSession.getComfortablePopulation());
            textViewMR.setText("MR:"+solveSession.getMutationRate());
        }
    }

    private void addCity(float x, float y)
    {
        cityPath.addCircle(x,y,8, Path.Direction.CCW);
        solveSession.addCity(x,y);
        onCityAddListener.onAdd(solveSession.getCityCount());
    }


    private void drawPath(Entity e){
        if(e==null)
            return;
        handler.post(new Runnable() {
            @Override
            public void run() {
                try {
                    wayPath.reset();

                    wayPath.moveTo((float) solveSession.getCity(e.getSeq(0)).getX(),(float) solveSession.getCity(e.getSeq(0)).getY());
                    for(int i=1;i<=e.getLength();++i){
                        wayPath.lineTo((float) solveSession.getCity(e.getSeq(i%e.getLength())).getX(),(float) solveSession.getCity(e.getSeq(i%e.getLength())).getY());
                    }
                    invalidate();
                }catch (Exception e){}

            }
        });
    }

    /*
    private void touch_move(float x, float y)
    {
        float dx = Math.abs(x - mX);
        float dy = Math.abs(y - mY);
        if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE)
        {
            cityPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
            mX = x;
            mY = y;
        }
    }

    private void touch_up()
    {
        cityPath.lineTo(mX, mY);
        // commit the path to our offscreen
        // 如果少了这一句，笔触抬起时myPath重置，那么绘制的线将消失
        myCanvas.drawPath(cityPath, cityPaint);
        // kill this so we don't double draw
        cityPath.reset();
    }
        */
    /**
     * 清除整个图像
     */
    public void reset()
    {
        removeAllViews();
        // 两种清除方法都必须加上后面这两步：
        // 路径重置
        isRunning=false;
        cityPath.reset();
        wayPath.reset();
        solveSession = new SolveSession();
        // 刷新绘制
        invalidate();

    }

    public void startSolving(){

        removeAllViews();
        textViewDistance = new TextView(getContext());
        textViewTurn = new TextView(getContext());
        textViewCP=new TextView(getContext());
        textViewMR=new TextView(getContext());
        addView(textViewDistance);
        addView(textViewTurn);
        addView(textViewCP);
        addView(textViewMR);

        SimpleThread solveThread = new SimpleThread(new SimpleThread.Runner() {
            @Override
            public void run() {
                solveSession.reset();
                solveSession.generateInitialEntities();
                Entity king=null;
                while (isRunning) {
                    solveSession.turn();
                    if (solveSession.getCurrentKing() != king) {
                        king = solveSession.getCurrentKing();
                        drawPath(king);
                    }
                }
            }
        },null);
        isRunning=true;
        solveThread.start();
    }
    public void stopSolving(){
        isRunning=false;
    }
    public boolean solveReady(){
        return  solveSession.getCityCount()>3;
    }

    public void createCityDemo(int cityCount){
        int r=(int)(Math.min(myBitmap.getHeight(),myBitmap.getWidth())*0.4);
        if(2*r*PI/cityCount<10)
            return;
        stopSolving();
        reset();
        int centerX=myBitmap.getWidth()/2;
        int centerY=myBitmap.getHeight()/2;
        for(int i=0;i<cityCount;++i){
            addCity( centerX+r*(float)Math.sin(i*2*PI/cityCount), centerY+r*(float)Math.cos(i*2*PI/cityCount));
        }
        solveSession.generateInitialEntities();
        invalidate();
    }









    public PaintLayout(Context context)
    {
        super(context);
        initialize();
    }

    public PaintLayout(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
        initialize();
    }

    public PaintLayout(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        initialize();
    }
    public boolean isRunning() {
        return isRunning;
    }
    public interface OnCityAddListener{
        void onAdd(int cityNum);
    }

    public void setOnCityAddListener(OnCityAddListener onCityAddListener) {
        this.onCityAddListener = onCityAddListener;
    }
    public void setSolveIP(int initialPopulation){
        solveSession.setInitialPopulation(initialPopulation);
    }
    public void setSolveCP(int comfortablePopulation){
        solveSession.setComfortablePopulation(comfortablePopulation);
        if(isRunning)
            textViewCP.setText("CP:"+solveSession.getComfortablePopulation());
    }
    public void setSolveMR(double mutationRate){
        solveSession.setMutationRate(mutationRate);
        if(isRunning)
            textViewMR.setText("MR:"+solveSession.getMutationRate());
    }
}